﻿using System.Collections.Concurrent;
using System.Web.Mvc;
using UIShell.OSGi;

namespace UIShell.OSGI.Mvc
{
    public class BundleRuntimeViewEngine : IViewEngine
    {
        private readonly ConcurrentDictionary<string, IViewEngine> _viewEngines =
            new ConcurrentDictionary<string, IViewEngine>();

        private readonly RazorViewEngine _defaultViewEngine;

        public BundleRuntimeViewEngine()
        {
            _defaultViewEngine = new RazorViewEngine();
            BundleRuntime.Instance.Framework.Bundles.ForEach(AddViewEngine);
        }

        public ViewEngineResult FindPartialView(ControllerContext controllerContext, string partialViewName, bool useCache)
        {
            var viewEngine = GetViewEngine(controllerContext);
            if (viewEngine == null) return new ViewEngineResult(new string[0]);

            return viewEngine.FindPartialView(controllerContext, partialViewName, useCache);
        }

        public ViewEngineResult FindView(ControllerContext controllerContext, string viewName, string masterName, bool useCache)
        {
            var viewEngine = GetViewEngine(controllerContext);
            if (viewEngine == null) return new ViewEngineResult(new string[0]);

            return viewEngine.FindView(controllerContext, viewName, masterName, useCache);
        }

        public void ReleaseView(ControllerContext controllerContext, IView view)
        {
            var viewEngine = GetViewEngine(controllerContext);
            if (viewEngine == null) return;

            viewEngine.ReleaseView(controllerContext, view);
        }

        private void AddViewEngine(IBundle bundle)
        {
            _viewEngines.TryAdd(bundle.SymbolicName, new BundleRazorViewEngine(bundle));
        }

        private IViewEngine GetViewEngine(ControllerContext controllerContext)
        {
            var symbolicName = controllerContext.RouteData.GetPluginSymbolicName();
            if (string.IsNullOrEmpty(symbolicName)) return _defaultViewEngine;

            IViewEngine viewEngine;
            return _viewEngines.TryGetValue(symbolicName, out viewEngine) ? viewEngine : _defaultViewEngine;
        }
    }
}
